package com.xh3140.xwidget.dialog.adapter;


import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;

import com.xh3140.xwidget.dialog.params.ItemParams;
import com.xh3140.xwidget.dialog.view.ItemView;
import com.xh3140.xwidget.dialog.view.ListView;

import java.util.ArrayList;
import java.util.List;

public class ListItemAdapter extends ListAdapter<ItemParams, ListItemAdapter.ItemViewHolder> {
  private boolean mIsRadio;
  private RecyclerView mRecyclerView;
  private int mCheckedIndex = -1;
  private final List<Integer> mCheckedIndexList = new ArrayList<>();

  public ListItemAdapter() {
    super(new DiffUtil.ItemCallback<ItemParams>() {
      @Override
      public boolean areItemsTheSame(@NonNull ItemParams oldItem, @NonNull ItemParams newItem) {
        return oldItem == newItem;
      }

      @Override
      public boolean areContentsTheSame(@NonNull ItemParams oldItem, @NonNull ItemParams newItem) {
        return false;
      }
    });
  }

  @Override
  public void submitList(@Nullable List<ItemParams> list) {
    super.submitList(list == null ? null : new ArrayList<>(list));
  }

  @Override
  public void submitList(@Nullable List<ItemParams> list, @Nullable Runnable commitCallback) {
    super.submitList(list == null ? null : new ArrayList<>(list), commitCallback);
  }

  @Override
  public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
    mRecyclerView = recyclerView;
  }

  @Override
  public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
    super.onDetachedFromRecyclerView(recyclerView);
    mRecyclerView = null;
  }

  @NonNull
  @Override
  public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    final ItemView view = new ItemView(parent.getContext(), mIsRadio);
    final ItemViewHolder holder = new ItemViewHolder(view);
    if (mIsRadio) {
      view.setOnCheckedChangeListener((itemView, isChecked) -> onRadioCheckedChange(holder.getAdapterPosition(), isChecked));
    } else {
      view.setOnCheckedChangeListener((itemView, isChecked) -> onMultiCheckedChange(holder.getAdapterPosition(), isChecked));
    }
    return holder;
  }

  @Override
  public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
    ((ItemView) holder.itemView).configView(getItem(position));
  }

  private void onRadioCheckedChange(int position, boolean isChecked) {
    if (isChecked) {
      if (mCheckedIndex >= 0) {
        // 手动取消前一个选中的项目
        final int prevIndex = mCheckedIndex;
        getItem(prevIndex).checked = false;
        if (mRecyclerView != null && mRecyclerView.isComputingLayout()) {
          mRecyclerView.post(() -> notifyItemChanged(prevIndex));
        } else {
          notifyItemChanged(prevIndex);
        }
      }
      // 选中当前项目
      mCheckedIndex = position;
      getItem(position).checked = true;
    } else {
      // 取消当前项目
      if (mCheckedIndex == position) {
        mCheckedIndex = -1;
      }
      getItem(position).checked = false;
    }
  }

  private void onMultiCheckedChange(int position, boolean isChecked) {
    getItem(position).checked = isChecked;
    if (isChecked) {
      if (!mCheckedIndexList.contains(position)) {
        mCheckedIndexList.add(position);
      }
    } else {
      if (mCheckedIndexList.contains(position)) {
        // 注意，这里必须是remove(Integer.valueOf(position))，不能是remove(position)
        // remove(position)表示移除指定索引位置的值，会抛出异常
        // remove(Integer.valueOf(position))表示移除数值是position的值，这个方法命名为removeAt更合适
        mCheckedIndexList.remove(Integer.valueOf(position));
      }
    }
  }

  public static final class ItemViewHolder extends ListView.ViewHolder {
    public ItemViewHolder(@NonNull ItemView itemView) {
      super(itemView);
    }
  }

  public void setIsRadio(boolean isRadio) {
    mIsRadio = isRadio;
  }

  public int getCheckedIndex() {
    return mCheckedIndex;
  }

  @NonNull
  public List<Integer> getCheckedIndexList() {
    return mCheckedIndexList;
  }
}
